﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using mdryden.Core.Data;
using mdryden.Core.Data.Sql;
using LastoRevival.Website.Models;
using LastoRevival.Website.Data.Sql.Converters;

namespace LastoRevival.Website.Data.Sql
{
	class SqlDataProvider : IDataProvider
	{

		private string connectionString;

		private EditSiteUserSettingsModelCreator editSiteUserSettingsCreator;
		private SiteUserSettingsCreator siteUserSettingsCreator;

		private SqlDataProvider(string connectionString)
		{
			this.connectionString = connectionString;
		}

		public static SqlDataProvider Create(string connectionString)
		{
			var editSiteUserSettingsCreator = new EditSiteUserSettingsModelCreator();
			var siteUserSettingsCreator = new SiteUserSettingsCreator();

			return new SqlDataProvider(connectionString)
			{
				editSiteUserSettingsCreator = editSiteUserSettingsCreator,
				siteUserSettingsCreator = siteUserSettingsCreator,
			};
		}

		#region Helper Methods

		private void ValidateRowCount(int expectedRowCount, DataTable table)
		{
			if (table.Rows.Count != expectedRowCount)
			{
				throw new InvalidRowCountException(expectedRowCount, table.Rows.Count);
			}
		}

		#endregion

		public SiteUserSettings GetCurrentUserSettings(int userID)
		{
			var command = new GetUserSettingsByUserIDCommand(userID);

			DataTable result;
			using (var manager = SqlManager.Create(connectionString, false))
			{
				result = manager.GetDataTable(command);
			}

			if (result.Rows.Count == 0)
			{
				return SiteUserSettings.CreateAnonymous();
			}

			ValidateRowCount(1, result);

			return siteUserSettingsCreator.Create(result.Rows[0]);
		}

		public EditSiteUserSettingsModel GetUserSettingsForEdit(int userID)
		{
			var command = new GetUserSettingsByUserIDCommand(userID);

			DataTable result;
			using (var manager = SqlManager.Create(connectionString))
			{
				result = manager.GetDataTable(command);
			}
			
			ValidateRowCount(1, result);

			return editSiteUserSettingsCreator.Create(result.Rows[0]);
		}


		public void UpdateUserSettings(EditSiteUserSettingsModel user)
		{
			var command = new UpdateUserSettingsCommand(user);

			using (var manager = SqlManager.Create(connectionString))
			{
				manager.ExecNonQuery(command);
			}
		}


		public void InsertUserSettings(int userID, SiteUserSettings settings)
		{
			var command = new InsertUserSettingsCommand(userID, settings);

			using (var manager = SqlManager.Create(connectionString))
			{
				manager.ExecNonQuery(command);
			}
		}
	}
}